package com.sap.health.tracker.threads;

import org.json.JSONArray;
import org.json.JSONObject;

import com.sap.health.tracker.R;
import com.sap.health.tracker.json.JSONFunctions;
import com.sap.health.tracker.library.StoreData;

import android.os.Bundle;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.Color;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.TableRow.LayoutParams;

public class HospitalsThread extends Activity {

	// JSON Response node names
    private static String KEY_SUCCESS = "success";
    private static String KEY_ROLE = "role";
	
	private TextView getPatientsErrorMsg;
	private TableLayout hospitalTable;
	private Context ctx;
	private String userID;
	private String sessionToken;
	
	private ProgressDialog loadingDialog;
	
	/**
	 * Runs when Class is first created.
	 * @param ctx
	 */
    public HospitalsThread(Context ctx, String userId, String sessionToken,
    		final TextView getPatientsErrorMsg,
    		final TableLayout hospitalTable,
    		final ImageView refresh) {
    	
    	this.getPatientsErrorMsg = getPatientsErrorMsg;
		this.hospitalTable = hospitalTable;   	
    	this.ctx = ctx;
    	this.userID = userId;
    	this.sessionToken = sessionToken;
    	
    	refresh.setOnClickListener(new OnClickListener() {
         	public void onClick(View v) {
         		refresh();
         	}
         });
    	
    	loadingDialog = new ProgressDialog(ctx);
        loadingDialog.setTitle("");
        loadingDialog.setMessage("Loading. Please wait...");
    }
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.profile_thread, menu);
        return true;
    }
    /**
     * Get the list of hospitals.
     */
    public void getHospitals(){   	
    	new Thread(new Runnable() {
    		@Override
            public void run() {
    			// let the user know it's busy.
            	createProgressDialog();
            	// get hospital list.
                JSONFunctions userFunction = new JSONFunctions();
                JSONObject json = userFunction.getHospitals(userID, sessionToken);
                 // check for login response
                try {
                	if (json.getString(KEY_SUCCESS) != null) {
                		//hide error message from user.
                		emptyErrorMessage();
                		boolean connectionStatus = false;
                		String res = json.getString(KEY_SUCCESS);
                		if(Integer.parseInt(res) == 1){
                			// Get the array from the JSON
                			JSONArray jsonAllHospitals = json.getJSONArray("allHospitals");
                			JSONArray jsonDoctors = json.getJSONArray("doctors");                         
                			StoreData store = new StoreData();
                			String role = (String) store.openType(ctx, String.class, KEY_ROLE);
                			// check if user is a doctor.
                			if("doctor".equals(role)){
	                			// make sure list isn't null.
                				if(!json.isNull("connectedHospitals")){
	                				JSONArray jsonConnectedHospitals = json.getJSONArray("connectedHospitals");
	                				// check if doctor is connected.
		                			for(int i = 0; i < jsonAllHospitals.length(); i++){
		                                // get each hospital				
		                				for(int n = 0; n < jsonConnectedHospitals.length(); n++){
		                					if(jsonAllHospitals.getJSONObject(i).getString("hospital_name").equalsIgnoreCase(jsonConnectedHospitals.getJSONObject(n).getString("hospital_name"))){
		                						connectionStatus = true;	
		                					}               				
		                				}  
		                				String doctors = "";
		                				if(!jsonDoctors.isNull(i)){
		                					for(int k = 0; k < jsonDoctors.getJSONArray(i).length(); k++){
		                						doctors += jsonDoctors.getJSONArray(i).getJSONObject(k).getString("user_firstname") + 
		                						" " + 
		                						jsonDoctors.getJSONArray(i).getJSONObject(k).getString("user_lastname");
		                						if(!jsonDoctors.isNull(i+1)){
		                							doctors += ", ";
		                						}
		                						
		                					}
		                				}
		                				// get details about the hospital.
		                				final String hospitalID = jsonAllHospitals.getJSONObject(i).getString("hospital_id");
		                				final String hospital = jsonAllHospitals.getJSONObject(i).getString("hospital_name");
		                				final String address = jsonAllHospitals.getJSONObject(i).getString("hospital_address");
		                				final String contact = jsonAllHospitals.getJSONObject(i).getString("hospital_contact");
		
		                				hospitalsDoctorUiHandler(hospitalID, hospital, address, contact, connectionStatus, doctors); 
		                				connectionStatus = false;
		                			}	
                				} else {
                					//There aren't any hospitals connected, so just show all the hospitals .
                					for(int i = 0; i < jsonAllHospitals.length(); i++){		                				
                						String doctors = "";
		                				if(!jsonDoctors.isNull(i)){
		                					for(int k = 0; k < jsonDoctors.getJSONArray(i).length(); k++){
		                						doctors += jsonDoctors.getJSONArray(i).getJSONObject(k).getString("user_firstname") + 
		                						" " + 
		                						jsonDoctors.getJSONArray(i).getJSONObject(k).getString("user_lastname");
		                						if(!jsonDoctors.isNull(i+1)){
		                							doctors += ", ";
		                						}
		                						
		                					}
		                				}			
		                				final String hospitalID = jsonAllHospitals.getJSONObject(i).getString("hospital_id");
		                				final String hospital = jsonAllHospitals.getJSONObject(i).getString("hospital_name");
		                				final String address = jsonAllHospitals.getJSONObject(i).getString("hospital_address");
		                				final String contact = jsonAllHospitals.getJSONObject(i).getString("hospital_contact");		
		                				hospitalsDoctorUiHandler(hospitalID, hospital, address, contact, connectionStatus, doctors); 
		                			}
                				}
                			} else {
                				// user is a patient, get all hospitals.
                				for(int i = 0; i < jsonAllHospitals.length(); i++){
	                                // get each hospital	                					
                					String doctors = "";
	                				if(!jsonDoctors.isNull(i)){
	                					for(int k = 0; k < jsonDoctors.getJSONArray(i).length(); k++){
	                						doctors += jsonDoctors.getJSONArray(i).getJSONObject(k).getString("user_firstname") + 
	                						" " + 
	                						jsonDoctors.getJSONArray(i).getJSONObject(k).getString("user_lastname");
	                						if(!jsonDoctors.isNull(i+1)){
	                							doctors += ", ";
	                						}	                						
	                					}
	                				}	                				
	                				final String hospitalID = jsonAllHospitals.getJSONObject(i).getString("hospital_id");
	                				final String hospital = jsonAllHospitals.getJSONObject(i).getString("hospital_name");
	                				final String address = jsonAllHospitals.getJSONObject(i).getString("hospital_address");
	                				final String contact = jsonAllHospitals.getJSONObject(i).getString("hospital_contact");	
	                				hospitalsPatientUiHandler(hospitalID, hospital, address, contact, doctors); 
	                			}
                			}
                                                         
                		}else{
                			//let the user know there was an error.
       		        	 	errorMessage("Error Accessing Database");
                		}
                     }
                 } catch (Exception e) {
                	 //TODO better exception handling.
                     e.printStackTrace();
                     // let the user know there was an error.
		        	 errorMessage("Network Connection Error");		        	 
                 }
                 dismissProgressDialog();
    		}                  	
    	}).start();		
    }
    
    /**
     * Hopsital UI handler for the patients.
     * @param hospitalID
     * @param hospital
     * @param address
     * @param contact
     * @param doctors
     */
    private void hospitalsPatientUiHandler(
    		final String hospitalID,
    		final String hospital,
    		final String address,
    		final String contact,
    		final String doctors){
    	
    	runOnUiThread(new Runnable() {
            public void run() {
            	// Create Column for patients name.	 
	           	// declare a new row
	           	TableRow row = new TableRow(ctx);
	           	// create text view.
	           	TextView nameTx = new TextView(ctx);
               	nameTx.setTextSize(18f);
               	nameTx.setLayoutParams(new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));           	 
	            nameTx.setText(hospital);	           	
	           	// add views to the row
	            row.addView(nameTx); 
	            row.setPadding(10, 10, 0, 0);             	 
	           	TextView addressTx = new TextView(ctx);
	           	addressTx.setText("Address: " + address);
	           	addressTx.setTextColor(Color.parseColor("#C4C4C4"));
	           	addressTx.setLayoutParams(new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));           	 
               	TableRow addresRow = new TableRow(ctx);
               	addresRow.addView(addressTx);
               	addresRow.setPadding(10, 0, 0, 10);	           	 
               	TableLayout containerRow = new TableLayout(ctx);
               	containerRow.addView(row);
               	containerRow.addView(addresRow);
               	// when suer clicks, give hopsital details.
               	containerRow.setOnClickListener(new View.OnClickListener() {
	                public void onClick(View v) {
	                	dialog(R.layout.popup, hospitalID,  hospital, contact, address, doctors);          	
	                }
	            }); 
               	// help dialog.
               	containerRow.setOnLongClickListener(new OnLongClickListener() { 
                    @Override
                    public boolean onLongClick(View v) {
                        helpDialog("These are the registered Hospitals along with " +
                        		"the associated doctors.");               	                	
                        return true;
                    }
                });	           	 
	           	 // add the row to the table layout
	           	 hospitalTable.addView(containerRow);	           	 
	           	// Used for creating a horizontal line to separate .	           	            	           	 
	           	View ruler = new View(ctx); ruler.setBackgroundColor(0xFFDEDEDE);
	           	hospitalTable.addView(ruler, new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, 2));      	 
            }
        });
    }
    
    
    /**
     * UI handler for the doctors.
     * @param hospitalID
     * @param hospital
     * @param address
     * @param contact
     * @param connectionStatus
     * @param doctors
     */
    private void hospitalsDoctorUiHandler(
    		final String hospitalID,
    		final String hospital,
    		final String address,
    		final String contact,
    		final boolean connectionStatus,
    		final String doctors){
    	
    	runOnUiThread(new Runnable() {
            public void run() {
	           	// declare a new row
	           	TableRow nameRow = new TableRow(ctx);
	           	// create text view.
	           	TextView nameTx = new TextView(ctx);
               	nameTx.setTextSize(18f);
               	nameTx.setLayoutParams(new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));           	 
               	// see if the doctor is connected to the hospital.
	           	if(connectionStatus){
	              	nameTx.setText(hospital + " (Connected)");
	           	} else {
	                nameTx.setText(hospital);
	           	}           	 
	           	// add views to the row
	           	nameRow.addView(nameTx); // you would actually want to set properties on this before adding it
	           	nameRow.setPadding(10, 10, 0, 0);           	 
	           	TextView addressTx = new TextView(ctx);
	           	addressTx.setText("Address: " + address);
	           	addressTx.setTextColor(Color.parseColor("#C4C4C4"));
		        addressTx.setLayoutParams(new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));           	 	           	 
              	TableRow addresRow = new TableRow(ctx);           	 
              	addresRow.addView(addressTx);
               	addresRow.setPadding(10, 0, 0, 10);	           	 
               	TableLayout containerRow = new TableLayout(ctx);
               	containerRow.addView(nameRow);
               	containerRow.addView(addresRow);
              	// give hospital information via a dialog. 
               	containerRow.setOnClickListener(new View.OnClickListener() {
	                public void onClick(View v) {
	                	dialog(R.layout.popup, hospitalID,  hospital, contact, address, connectionStatus, doctors);          	
	                }
	            }); 
	           	 
	           	// add the row to the table layout
	           	hospitalTable.addView(containerRow);
	           	
	           	//Used for creating a horizontal line to separate .	           	          	           	 
	           	View ruler = new View(ctx); ruler.setBackgroundColor(0xFFDEDEDE);
	           	hospitalTable.addView(ruler, new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, 2));      	 
            }
        });
    }
    
    /**
     * Dialog of patients, only shows details of the hospital.
     * @param itemsPopup
     * @param hospitalID
     * @param hospitalName
     * @param hospitalContact
     * @param hospitalAddress
     * @param doctors
     */
    private void dialog(int itemsPopup, final String hospitalID, final String hospitalName,
    		final String hospitalContact, final String hospitalAddress, final String doctors){
		// new dialog.
		final Dialog dialog = new Dialog(ctx);
		dialog.setContentView(itemsPopup);
		dialog.setTitle(hospitalName);
		// create row.
		TableRow contactRow = new TableRow(ctx);
		TableRow addressRow = new TableRow(ctx);
		TableRow doctorsRow = new TableRow(ctx);
      	// create text view.
      	TextView contactTx = new TextView(ctx);
      	TextView addressTx = new TextView(ctx);
      	TextView doctorsTx = new TextView(ctx);
      	// Create Text Views
      	contactTx.setLayoutParams(new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));           	 
      	addressTx.setLayoutParams(new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));           	 
      	doctorsTx.setLayoutParams(new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));           	 
      	// set text to textViews.
      	contactTx.setText("Contact: " + hospitalContact);
      	addressTx.setText("Address: " + hospitalAddress);
      	doctorsTx.setText("Doctors: " + doctors);
      	// add views to the row
      	contactRow.addView(contactTx);
      	addressRow.addView(addressTx);
      	doctorsRow.addView(doctorsTx);
      	//set padding to rows.
      	contactRow.setPadding(10, 10, 0, 10);
      	addressRow.setPadding(10, 10, 0, 10);
      	doctorsRow.setPadding(10, 10, 0, 10);
      	// new table.
      	TableLayout dialogTable = (TableLayout) dialog.findViewById(R.id.dialogTable);           
      	// add the row to the table layout
      	dialogTable.addView(contactRow);
      	dialogTable.addView(addressRow);
      	dialogTable.addView(doctorsRow);
      	// dississ button.
		Button dialogButton = (Button) dialog.findViewById(R.id.dismiss);
		// if button is clicked, close the custom dialog
		dialogButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				dialog.dismiss();
			}
		});
		dialog.show();
	}
    
    
    /**
     * Dialog for doctors, options to connect to hospital
     * @param itemsPopup
     * @param hospitalID
     * @param hospitalName
     * @param hospitalContact
     * @param hospitalAddress
     * @param connectionStatus
     * @param doctors
     */
    private void dialog(int itemsPopup, final String hospitalID, final String hospitalName,
    		final String hospitalContact, final String hospitalAddress,
    		final boolean connectionStatus, final String doctors){

		// new dialog.
		final Dialog dialog = new Dialog(ctx);
		dialog.setContentView(itemsPopup);
		dialog.setTitle(hospitalName);
		// create rows.
		TableRow contactRow = new TableRow(ctx);
		TableRow addressRow = new TableRow(ctx);
		TableRow doctorsRow = new TableRow(ctx);
      	// create text view.
      	TextView contactTx = new TextView(ctx);
      	TextView addressTx = new TextView(ctx);
      	TextView doctorsTx = new TextView(ctx);
      	// wrap text
     	contactTx.setLayoutParams(new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));           	 
      	addressTx.setLayoutParams(new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));           	 
      	doctorsTx.setLayoutParams(new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));           	 
      	// set text to textview
      	contactTx.setText("Contact: " + hospitalContact);
      	addressTx.setText("Address: " + hospitalAddress);
      	doctorsTx.setText("Doctors: " + doctors);
      	// add views to the row
      	contactRow.addView(contactTx);
      	addressRow.addView(addressTx);
      	doctorsRow.addView(doctorsTx);
      	// set padding to row.
      	contactRow.setPadding(10, 10, 0, 10);
      	addressRow.setPadding(10, 10, 0, 10);
      	doctorsRow.setPadding(10, 10, 0, 10);
      	// create table
      	TableLayout dialogTable = (TableLayout) dialog.findViewById(R.id.dialogTable);            
      	// add the row to the table layout
      	dialogTable.addView(contactRow);
      	dialogTable.addView(addressRow);
      	dialogTable.addView(doctorsRow);
      	// check connection status, if connected, remove btn, else add btn.
      	if(connectionStatus){
	      	Button remove = new Button(ctx);
	      	remove.setText("Remove");
	      	TableLayout btnTable = (TableLayout) dialog.findViewById(R.id.btnTable);    
	      	btnTable.addView(remove);      	
			// if button is clicked, remove hospital connection.
			remove.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					addRemoveHospital(hospitalID, dialog, "remove");
				}
			});
		} else {
			Button add = new Button(ctx);
			add.setText("Add");
	      	TableLayout btnTable = (TableLayout) dialog.findViewById(R.id.btnTable);    
	      	btnTable.addView(add);     	
			// if button is clicked, add hosptial
			add.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					addRemoveHospital(hospitalID, dialog, "add");
				}
			});
		} 	
		Button dialogButton = (Button) dialog.findViewById(R.id.dismiss);
		// if button is clicked, close the custom dialog
		dialogButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				dialog.dismiss();
			}
		});
		dialog.show();
	}
    /**
     * Add or remove the hospital.
     * @param hospitalID
     * @param dialog
     * @param addremoveSwitch
     */
    public void addRemoveHospital(final String hospitalID, final Dialog dialog, final String addremoveSwitch){ 	
    	new Thread(new Runnable() {
    		@Override
            public void run() {
    			// show progress dialog.
            	createProgressDialog();
            	// connect to server.
                JSONFunctions userFunction = new JSONFunctions();
                JSONObject json = null;
                if("add".equals(addremoveSwitch)){
                	json = userFunction.addHospital(userID, sessionToken, hospitalID);
                } else if("remove".equals(addremoveSwitch)){
                	json = userFunction.removeHospital(userID, sessionToken, hospitalID);
                }
                // check for login response
                try {
                	if (json.getString(KEY_SUCCESS) != null) {
                		String res = json.getString(KEY_SUCCESS);
                		if(Integer.parseInt(res) == 1){
                			// success, dismiss dialog and refresh.
                			dialog.dismiss();
                			refresh();                                                       
                		}else{
                			//let the user know there was an error.
       		        	 	simpleDialog("Error Accessing Database");
                		}
                     }
                 } catch (Exception e) {
                	 //TODO better exception handling.
                     e.printStackTrace();
                     // let the user know there was an error.
		        	 simpleDialog("Network Connection Error");
                 }
                 dismissProgressDialog();
    		}                  	
    	}).start();		
    }
    /**
     * A simple dialog for showing a simple message.
     * @param title
     */
    private void simpleDialog(final String title){
    	runOnUiThread(new Runnable() {
			public void run() {
				// custom dialog
				final Dialog dialog = new Dialog(ctx);
				dialog.setContentView(R.layout.popup);
				dialog.setTitle(title);		 	
				Button dialogButton = (Button) dialog.findViewById(R.id.dismiss);
				// if button is clicked, close the custom dialog
				dialogButton.setOnClickListener(new OnClickListener() {
					@Override
					public void onClick(View v) {
						dialog.dismiss();
					}
				});	 
				dialog.show();
			}
		}); 
		
	}
    
    /**
     * Refresh the layout.
     */
    private void refresh(){
    	runOnUiThread(new Runnable() {
            public void run() {
            	// remove the views from hospital table.
            	hospitalTable.removeAllViews();   	
            	getHospitals();
            }
    	});
    }
    /**
     * Empty the error message.
     */
    private void emptyErrorMessage(){
    	runOnUiThread(new Runnable() {
			public void run() {
				getPatientsErrorMsg.setText("");
             	getPatientsErrorMsg.setVisibility(View.INVISIBLE);
            }
		});
    }
    /**
     * Show error message.
     * @param error
     */
    private void errorMessage(final String error){
    	runOnUiThread(new Runnable() {
			public void run() {
				getPatientsErrorMsg.setText(error);
             	getPatientsErrorMsg.setVisibility(View.VISIBLE);
            }
		});
    }
    /**
     * Dismiss the progress dialog.
     */
    private void dismissProgressDialog(){
    	runOnUiThread(new Runnable() {
            public void run() {
            	// hide progress spinner now that thread is finished.
            	//progressSpinner.setVisibility(View.INVISIBLE);
            	loadingDialog.hide();
            }
        });
    }
    /**
     * Create progress Dialog.
     */
    private void createProgressDialog(){
    	runOnUiThread(new Runnable() {
            public void run() {
            	// show progress spinner to let the user know it's working.
            	//progressSpinner.setVisibility(View.VISIBLE);
            	loadingDialog.show();
            }
        });
    }
    /**
     * Help message dialog.
     * @param message
     */
    private void helpDialog(final String message){  	
		// new dialog
		final Dialog dialog = new Dialog(ctx);
		dialog.setContentView(R.layout.popup);
		dialog.setTitle("Help options");		
		TableRow noteRow = new TableRow(ctx);
      	// create text view.
      	TextView noteTx = new TextView(ctx);
      	noteTx.setText(message);
      	noteTx.setLayoutParams(new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));           	 
      	// add views to the row
      	noteRow.addView(noteTx);   	 
      	noteRow.setPadding(10, 10, 0, 10);
      	TableLayout dialogTable = (TableLayout) dialog.findViewById(R.id.dialogTable);    
      	// add the row to the table layout
      	dialogTable.addView(noteRow);		
		Button dialogButton = (Button) dialog.findViewById(R.id.dismiss);
		// if button is clicked, close the custom dialog
		dialogButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				dialog.dismiss();
			}
		}); 
		dialog.show();	
	}
}
